#include "filesystem.h"

#include <dirent.h>
#include <stdio.h>

std::string getAppPath()
{
    static std::string app_path = "";
    static int found = false;

    if( found )
        return app_path;

    char appPath[MAX_PATH] = "";
    app_path = "";

    GetModuleFileName(NULL, appPath, MAX_PATH);
    app_path = appPath;
    app_path = app_path.substr(0, app_path.rfind("\\"));

    found = true;

    return app_path;
}

std::string fixSlashes(std::string instr, int type)
{
    unsigned int i = SLASHES_TO_STANDARD;

    if( type == SLASHES_TO_STANDARD )
        i = instr.find("\\");
    else if( type == SLASHES_TO_WINDOWS )
        i = instr.find("/");

    while( i != std::string::npos )
    {
        if( type == SLASHES_TO_STANDARD ) {
            instr.replace(i, 1, "/");
            i = instr.find("\\", i+1); }
        else if( type == SLASHES_TO_WINDOWS ) {
            instr.replace(i, 1, "\\");
            i = instr.find("/", i+1); }
    }

  return instr;
}

std::string getFilePath(std::string fullpath)
{
    fullpath = fixFileRelatives(fullpath);

    unsigned int foundpos = fullpath.rfind("/");
    if( foundpos != std::string::npos )
        fullpath = fullpath.substr(0, fullpath.rfind("/"));
    else
        fullpath = "./"; // resides in "this" directory

    return fullpath;
}

std::string getFileName(std::string fullpath)
{
    fullpath = fixSlashes(fullpath, SLASHES_TO_STANDARD);
    fullpath = fullpath.substr(fullpath.rfind("/")+1);
    return fullpath;
}

std::string fixFileRelatives(std::string instr)
{
    instr = fixSlashes(instr, SLASHES_TO_STANDARD);

	/* Keep any leading ../ and ./ */
	std::string prefix;
	for(unsigned int i = 0; i < instr.length(); i++)
	{
		char c = instr.at(i);
		if( c == '.' || c == '/' )
		{
			prefix.append(1, c);
		}
		else
			break;
	}
	if( prefix.length() )
		instr.erase(0, prefix.length());

    /* Strip out any "../", and their previous directory (if sane) */
    unsigned int foundpos = instr.find("../");
    while( foundpos != std::string::npos )
    {
        unsigned int prevslash = instr.substr(0, foundpos - 1).rfind("/");

        if( prevslash != std::string::npos )
            instr.erase(prevslash+1, foundpos - prevslash + 2);
            // +2 because of length of "../" - length of "/"
        else
        {
            instr.erase(foundpos - 1, 3); // 3 = length of "../"
        }

        foundpos = instr.find("../");
    }

    // now strip out any "./"
    foundpos = instr.find("./");
    while( foundpos != std::string::npos)
    {
        instr.erase(foundpos, 2); // 2, length of "./"

        foundpos = instr.find("./");
    }

    return prefix + instr;
}

void getDirectory(std::string directory, std::vector<std::string> &files,
    std::string sext)
{
    DIR *dir;
    dir = opendir(directory.c_str());

    if( dir != NULL )
    {
        dirent *dirp;
        char ext[128];
        while( (dirp = readdir(dir)) != NULL )
        {
            char *foundpos = strrchr(dirp->d_name, '.');

            if( foundpos )
                strncpy((char*)&ext, foundpos+1, 128);
            else
                strncpy((char*)&ext, "", 128);

            if( strcmp(dirp->d_name, ".") != 0 &&
                strcmp(dirp->d_name, "..") != 0 )
            {
                if( sext == "" || sext.compare(ext) == 0 )
                files.push_back(std::string(dirp->d_name));
            }
        }
        closedir(dir);
    }
}

int fileExists(std::string fullpath)
{
    FILE *file;
    file = fopen(fullpath.c_str(), "r");

    int success = file != NULL;

    if( file )
        fclose(file);

    return success;
}
